{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "aa504031-8204-4efd-a66d-0d4341a54a8e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "231663ac",
   "metadata": {},
   "source": [
    "Apriori算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7015b675",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造单项集\n",
    "def createC1(dataSet):\n",
    "    C = []\n",
    "    for transaction in dataSet:\n",
    "        for item in transaction:\n",
    "            if [item] not in C:\n",
    "                C.append([item])\n",
    "    C.sort()\n",
    "    return list(map(frozenset,C))\n",
    "\n",
    "\n",
    "#计算Ck的项集在原始记录D中的支持度\n",
    "def scanD(D,Ck,minSupport):\n",
    "    ssCnt = {}\n",
    "    for tid in D:\n",
    "        for can in Ck:\n",
    "            if can.issubset(tid):\n",
    "                ssCnt[can] = ssCnt.get(can,0)+1\n",
    "    numItems = float(len(D))\n",
    "    retList = []\n",
    "    supportData = {}\n",
    "    for key in ssCnt:\n",
    "        support = ssCnt[key]/numItems\n",
    "        if support >= minSupport:\n",
    "            retList.insert(0,key)\n",
    "        supportData[key] = support\n",
    "    return retList,supportData\n",
    "\n",
    "# 生成新的候选项集\n",
    "def aprioriGen(Ck,k):\n",
    "    retList = []\n",
    "    lenCk = len(Ck)\n",
    "    for i in range(lenCk):\n",
    "        for j in range(i+1,lenCk):\n",
    "            L1 = list(Ck[i])[:k-2]\n",
    "            L2 = list(Ck[j])[:k-2]\n",
    "            L1.sort()\n",
    "            L2.sort()\n",
    "            if L1 == L2:\n",
    "                retList.append(Ck[i]|Ck[j])\n",
    "    return retList\n",
    "\n",
    "# 返回所有满足最小支持度的项集\n",
    "def apriori(D,minSupport):\n",
    "    C1=createC1(D)\n",
    "    L1,suppData = scanD(D,C1,minSupport)\n",
    "    L=[L1]\n",
    "    k=2\n",
    "    while (len(L[k-2])>0):\n",
    "        Ck = aprioriGen(L[k-2],k)\n",
    "        Lk,supK=scanD(D,Ck,minSupport)\n",
    "        suppData.update(supK)\n",
    "        L.append(Lk)\n",
    "        k+=1\n",
    "    return L,suppData\n",
    "\n",
    "# 满足最小置信度要求的规则\n",
    "def calcConf(freqSet,H,supportData,brl,minConf=0.7):\n",
    "    prunedH = []\n",
    "    for conseq in H:\n",
    "        conf=supportData[freqSet]/supportData[freqSet-conseq]\n",
    "        if conf >= minConf:\n",
    "            print(freqSet - conseq,'-->',conseq,'conf',conf)\n",
    "            brl.append((freqSet-conseq,conseq,conf))\n",
    "            prunedH.append(conseq)\n",
    "    return prunedH\n",
    "\n",
    "# 对频繁项集中元素超过2的项集进行合并\n",
    "def rulesFormConseq(freqSet,H,suppData,brl,minConf=0.7):\n",
    "    m = len(H[0])\n",
    "    if len(freqSet)>m+1:\n",
    "        Hmp1 = aprioriGen(H,m+1)\n",
    "        Hmp1 = calcConf(freqSet,Hmp1,suppData,brl,minConf)\n",
    "        if len(Hmp1)>1:\n",
    "            rulesFormConseq(freqSet,Hmp1,suppData,brl,minConf)\n",
    "\n",
    "# 根据频繁项集和最小可信度生产规则\n",
    "def generateRules(L,supportData,minConf=0.7):\n",
    "    bigRuleList=[]\n",
    "    for i in range(1,len(L)):\n",
    "        for freqSet in L[i]:\n",
    "            H1 = [frozenset([item]) for item in freqSet]\n",
    "            if i>1:\n",
    "                rulesFormConseq(freqSet,H1,supportData,bigRuleList,minConf)\n",
    "            else:\n",
    "                calcConf(freqSet,H1,supportData,bigRuleList,minConf)\n",
    "    return bigRuleList"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "fa13261f-ff06-4d21-a4e5-d809fdc50176",
   "metadata": {},
   "outputs": [],
   "source": [
    "def val2colindex(val,colname):\n",
    "    if(val==1):\n",
    "        return colname\n",
    "    else:\n",
    "        return 0\n",
    "def loadExcel(fname):\n",
    "    data2Dlist=[]\n",
    "    pd1 = pd.read_excel(fname,'Sheet1')\n",
    "    print('读入的数据文件首5行：')\n",
    "    print(pd1.head())\n",
    "    for cn in pd1.columns:\n",
    "        if(cn!='ID'):\n",
    "            pd1[cn]=pd1[cn].apply(lambda val:val2colindex(val,cn))\n",
    "    print('转为发卡行名后的数据文件首5行：')\n",
    "    print(pd1.head())\n",
    "\n",
    "    for index, row in pd1.iterrows():\n",
    "        list1 = row.tolist()\n",
    "        list1.pop(0)\n",
    "        while 0 in list1:\n",
    "            list1.remove(0)\n",
    "        data2Dlist.append(list1)\n",
    "\n",
    "    print('转化后的2维列表前5项：')\n",
    "    print(data2Dlist[:4])\n",
    "    return data2Dlist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "162a639a-5e04-4adc-bbc8-ba1d45b2e361",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "读入的数据文件首5行：\n",
      "      ID  gs  ny  zg  js  jt  yc  zs\n",
      "0  10001   1   0   1   1   0   0   1\n",
      "1  10002   1   1   1   0   1   1   0\n",
      "2  10003   0   0   1   0   0   1   1\n",
      "3  10004   0   0   0   0   1   0   1\n",
      "4  10005   0   0   0   0   1   1   0\n",
      "转为发卡行名后的数据文件首5行：\n",
      "      ID  gs  ny  zg  js  jt  yc  zs\n",
      "0  10001  gs   0  zg  js   0   0  zs\n",
      "1  10002  gs  ny  zg   0  jt  yc   0\n",
      "2  10003   0   0  zg   0   0  yc  zs\n",
      "3  10004   0   0   0   0  jt   0  zs\n",
      "4  10005   0   0   0   0  jt  yc   0\n",
      "转化后的2维列表前5项：\n",
      "[['gs', 'zg', 'js', 'zs'], ['gs', 'ny', 'zg', 'jt', 'yc'], ['zg', 'yc', 'zs'], ['jt', 'zs']]\n"
     ]
    }
   ],
   "source": [
    "myData1 = loadExcel('ch09_creditcard_info.xlsx')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "284344be-eb37-40da-8eec-b717330ec348",
   "metadata": {},
   "outputs": [],
   "source": [
    "L1,suD2=apriori(myData1,0.22)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4242e853-cac5-45b1-a644-85ecb3d46af5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[frozenset({'yc'}),\n",
       "  frozenset({'ny'}),\n",
       "  frozenset({'jt'}),\n",
       "  frozenset({'zs'}),\n",
       "  frozenset({'zg'}),\n",
       "  frozenset({'js'}),\n",
       "  frozenset({'gs'})],\n",
       " [frozenset({'ny', 'zs'}),\n",
       "  frozenset({'js', 'yc'}),\n",
       "  frozenset({'js', 'jt'}),\n",
       "  frozenset({'jt', 'zs'}),\n",
       "  frozenset({'yc', 'zs'}),\n",
       "  frozenset({'gs', 'jt'}),\n",
       "  frozenset({'jt', 'zg'}),\n",
       "  frozenset({'gs', 'ny'}),\n",
       "  frozenset({'ny', 'zg'}),\n",
       "  frozenset({'jt', 'ny'}),\n",
       "  frozenset({'gs', 'yc'}),\n",
       "  frozenset({'yc', 'zg'}),\n",
       "  frozenset({'jt', 'yc'}),\n",
       "  frozenset({'ny', 'yc'}),\n",
       "  frozenset({'gs', 'js'}),\n",
       "  frozenset({'gs', 'zg'}),\n",
       "  frozenset({'gs', 'zs'}),\n",
       "  frozenset({'zg', 'zs'})],\n",
       " [frozenset({'gs', 'jt', 'zs'}), frozenset({'jt', 'ny', 'zs'})],\n",
       " []]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "7298e30a-3067-41fb-9157-b21afe51ddca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{frozenset({'gs'}): 0.5,\n",
       " frozenset({'js'}): 0.44,\n",
       " frozenset({'zg'}): 0.44,\n",
       " frozenset({'zs'}): 0.56,\n",
       " frozenset({'jt'}): 0.68,\n",
       " frozenset({'ny'}): 0.54,\n",
       " frozenset({'yc'}): 0.48,\n",
       " frozenset({'zg', 'zs'}): 0.28,\n",
       " frozenset({'js', 'zs'}): 0.2,\n",
       " frozenset({'gs', 'zs'}): 0.32,\n",
       " frozenset({'js', 'zg'}): 0.2,\n",
       " frozenset({'gs', 'zg'}): 0.26,\n",
       " frozenset({'gs', 'js'}): 0.22,\n",
       " frozenset({'ny', 'yc'}): 0.22,\n",
       " frozenset({'jt', 'yc'}): 0.3,\n",
       " frozenset({'yc', 'zg'}): 0.22,\n",
       " frozenset({'gs', 'yc'}): 0.26,\n",
       " frozenset({'jt', 'ny'}): 0.4,\n",
       " frozenset({'ny', 'zg'}): 0.22,\n",
       " frozenset({'gs', 'ny'}): 0.22,\n",
       " frozenset({'jt', 'zg'}): 0.28,\n",
       " frozenset({'gs', 'jt'}): 0.36,\n",
       " frozenset({'yc', 'zs'}): 0.24,\n",
       " frozenset({'jt', 'zs'}): 0.4,\n",
       " frozenset({'js', 'ny'}): 0.2,\n",
       " frozenset({'js', 'jt'}): 0.26,\n",
       " frozenset({'js', 'yc'}): 0.22,\n",
       " frozenset({'ny', 'zs'}): 0.3,\n",
       " frozenset({'gs', 'js', 'zs'}): 0.12,\n",
       " frozenset({'gs', 'zg', 'zs'}): 0.14,\n",
       " frozenset({'gs', 'jt', 'ny'}): 0.2,\n",
       " frozenset({'gs', 'jt', 'yc'}): 0.18,\n",
       " frozenset({'jt', 'ny', 'zg'}): 0.16,\n",
       " frozenset({'jt', 'yc', 'zg'}): 0.12,\n",
       " frozenset({'gs', 'jt', 'zg'}): 0.16,\n",
       " frozenset({'gs', 'ny', 'yc'}): 0.1,\n",
       " frozenset({'ny', 'yc', 'zg'}): 0.12,\n",
       " frozenset({'gs', 'ny', 'zg'}): 0.1,\n",
       " frozenset({'jt', 'ny', 'yc'}): 0.14,\n",
       " frozenset({'gs', 'yc', 'zg'}): 0.14,\n",
       " frozenset({'yc', 'zg', 'zs'}): 0.14,\n",
       " frozenset({'js', 'jt', 'yc'}): 0.1,\n",
       " frozenset({'gs', 'js', 'jt'}): 0.12,\n",
       " frozenset({'gs', 'js', 'yc'}): 0.14,\n",
       " frozenset({'jt', 'ny', 'zs'}): 0.24,\n",
       " frozenset({'ny', 'yc', 'zs'}): 0.14,\n",
       " frozenset({'jt', 'yc', 'zs'}): 0.16,\n",
       " frozenset({'jt', 'zg', 'zs'}): 0.18,\n",
       " frozenset({'ny', 'zg', 'zs'}): 0.14,\n",
       " frozenset({'gs', 'jt', 'zs'}): 0.24,\n",
       " frozenset({'gs', 'ny', 'zs'}): 0.14,\n",
       " frozenset({'gs', 'yc', 'zs'}): 0.16,\n",
       " frozenset({'gs', 'js', 'ny'}): 0.06}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "suD2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35a134b6",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
